package io.mft.commons.db.mapper.proxyinvoker;

import java.lang.reflect.Method;
import java.util.List;

import cn.hutool.core.util.ReflectUtil;
import io.mft.commons.db.mapper.BeanListMapping;
import io.mft.commons.db.mapper.BeanListMappingParser;
import io.mft.commons.db.mapper.Pager;
import io.mft.commons.db.mapper.SQLQueryMapResult;
import io.mft.commons.db.mapper.annotation.BeanMapper;
import io.mft.commons.db.mapper.builder.DbOperateType;
import io.mft.commons.db.mapper.proxyinvoker.invoker.BeanListMapperProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.BeanMapperProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.BoolProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.DBPageProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.NumberProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.PagerProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.SQLQueryMapResultProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.TbDIUProxyInvoker;
import io.mft.commons.db.mapper.proxyinvoker.invoker.VoidProxyInvoker;
import io.mft.commons.function.response.kv.PageObject;

public enum ProxyInvokerType {
	

	None(null),DBPageProxy(DBPageProxyInvoker.class), BoolProxy(BoolProxyInvoker.class), NumberProxy(NumberProxyInvoker.class),SQLQueryMapResultProxy(SQLQueryMapResultProxyInvoker.class),BeanMapperProxy(BeanMapperProxyInvoker.class),BeanListMapperProxy(BeanListMapperProxyInvoker.class),VoidProxy(VoidProxyInvoker.class),TbDIUProxy(TbDIUProxyInvoker.class),PagerQueryProxy(PagerProxyInvoker.class);
	private IProxyInvoker<?> proxyInvoker;
	public String mappingToBeanId() {
		return ProxyInvokerType.class.getName()+"."+name();
	}
	private ProxyInvokerType(Class<?> classType) {
		if (classType!=null) {
			proxyInvoker=(IProxyInvoker<?>)ReflectUtil.newInstance(classType);
		}
		
	}
	public IProxyInvoker<?> proxyInvoker() {
		return proxyInvoker;
	}
	public static ProxyInvokerType parseProxyInvokerType(Method method,DbOperateType dbOperateType) {
		if (dbOperateType!=DbOperateType.mybatise) {
			return ProxyInvokerType.TbDIUProxy;
		}
		Class<?> returnType = method.getReturnType();
		if (isBool(returnType)) {//返回SQL执行是否影响结果
			return ProxyInvokerType.BoolProxy;
		}
		if (isNumber(returnType)) {//返回SQL执行影响结果集数
			return ProxyInvokerType.NumberProxy;
		}
		if (isVoid(returnType)) {//无结果集返回SQL执行
			return ProxyInvokerType.VoidProxy;
		}
		if (isMapperType(returnType)) {//单一bean映射
			return ProxyInvokerType.BeanMapperProxy;
		}
		if (returnType.equals(PageObject.class)) {//分页查询
			return ProxyInvokerType.DBPageProxy;
		}
		if (returnType.equals(SQLQueryMapResult.class)) {//普通DataRow 结果集查询
			return ProxyInvokerType.SQLQueryMapResultProxy;
		}
		if (returnType.equals(Pager.class)) {//分页查询
			return ProxyInvokerType.PagerQueryProxy;
		}
		if (isMapperType(returnType)) {//单一bean映射
			return ProxyInvokerType.BeanMapperProxy;
		}
		if (returnType.equals(List.class)) {//集合bean映射查询
			BeanListMapping beanListMapping=BeanListMappingParser.parse(method);
			if (beanListMapping.isCanMapping()) {
				return ProxyInvokerType.BeanListMapperProxy;
			}
		}
		return ProxyInvokerType.None;
	}
	private static boolean isMapperType(Class<?> returnType) {
		BeanMapper beanMapper=returnType.getAnnotation(BeanMapper.class);
		return beanMapper==null?false:true;
	}
	private static boolean isBool(Class<?> returnType) {
		boolean s=boolean.class.equals(returnType);
		boolean t=returnType.equals(Boolean.class);
		return s||t;
	}
	private static boolean isNumber(Class<?> returnType) {
		boolean s=int.class.equals(returnType);
		boolean t=Integer.class.equals(returnType);
		return s||t;
	}
	
	private static boolean isVoid(Class<?> returnType) {
		boolean s=void.class.equals(returnType);
		boolean t=returnType.equals(Void.class);
		return s||t;
	}
}
